package x.ovo.wechat.bot.impl.contact;

import org.dromara.hutool.core.collection.CollUtil;
import x.ovo.wechat.bot.core.Context;
import x.ovo.wechat.bot.core.contact.ContactManager;
import x.ovo.wechat.bot.core.contact.Contactable;
import x.ovo.wechat.bot.core.contact.RetrievalType;
import x.ovo.wechat.bot.core.entity.Contact;
import x.ovo.wechat.bot.core.entity.Member;
import x.ovo.wechat.bot.core.enums.ContactType;
import x.ovo.wechat.bot.core.http.WechatApi;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public enum HashMapContactManager implements ContactManager {
    INSTANCE;

    private final Context ctx = Context.INSTANCE;
    private final WechatApi api = ctx.getApi();
    private final Map<String, Contactable> contacts = new HashMap<>();
    private final Map<String, Collection<Member>> groups = new HashMap<>();

    @Override
    public void init() {
        new UserNameStrategy().init();
        new NickNameStrategy().init();
        new RemarkStrategy().init();
        ContactManager.super.init();
    }

    @Override
    public Contact get(String id) {
        return this.get(id, RetrievalType.USER_NAME);
    }

    @Override
    public Contact get(String id, RetrievalType type) {
        return (Contact) this.getStratrgy(type).get(this.contacts.values().iterator(), id);
    }

    @Override
    public void remove(String id) {
        this.remove(id, RetrievalType.USER_NAME);
    }

    @Override
    public void remove(String id, RetrievalType type) {
        this.getStratrgy(type).remove(this.contacts.values().iterator(), id);
    }

    @Override
    public void syncRecent(Collection<Contact> contacts) {
        if (CollUtil.isEmpty(contacts)) return;
        contacts.forEach(contact -> {
            contact.format();
            contact.getMemberList().forEach(Member::format);
            this.contacts.put(contact.getUserName(), contact);
            this.groups.put(contact.getUserName(), contact.getMemberList());
        });
    }

    @Override
    public void flushContact() {
        Contact me = this.ctx.getSession().getContact();
        this.contacts.put(me.getUserName(), me);
        this.api.listContact().forEach(contact -> {
            contact.format();
            this.contacts.put(contact.getUserName(), contact);
        });
        log.info("刷新联系人列表完成，共 {} 位联系人", this.contacts.size());
    }

    @Override
    public void flushGroup() {
        this.contacts.values().forEach(contact -> {
            if (ContactType.GROUP.equals(contact.getType())) {
                List<Member> members = this.api.listMember(contact.getUserName());
                members.forEach(Member::format);
                this.groups.put(contact.getUserName(), members);
                log.info("已加载群 [{}] 共 {} 成员", contact.getNickName(), CollUtil.size(members));
            }
        });
    }

    @Override
    public Member get(String group, String id, RetrievalType type) {
        return (Member) this.getStratrgy(type).get(this.groups.get(group).iterator(), id);
    }

    @Override
    public void remove(String group, String id, RetrievalType type) {

    }
}
